home *** CD-ROM | disk | FTP | other *** search
- .386
-
-
- _TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
-
- ASSUME cs:_TEXT
-
-
-
- extern _rand_table:dword
-
- extern _sin_table:word
- extern _asin_table:word
-
- extern _tan_table1:dword
- extern _tan_table3:dword
- extern _tan_table4:dword
-
- extern _atan_table1:word
- extern _atan_table2:word
- extern _atan_table3:word
- extern _atan_table4:word
-
- extern _log2_table:word
- extern _exp2_table:word
- extern _sqrt_table:word
-
-
- public _rnd1
- public _rnd2
- public _rnd3
-
- _rnd1 dd 193
- _rnd2 dd 0
- _rnd3 dd 122231
-
-
-
- public rand32_
-
- rand32_ proc near
- push edx
-
- mov edx,[_rnd3]
- mov eax,[_rnd1]
- and edx,03FFh
-
- mul edx
- inc [_rnd2]
- mov edx,[_rnd2]
- and edx,16383
- jne r_a
-
- push edx
- shr edx,14
- add [_rnd3],3
- and edx,16383
- add eax,[_rand_table+edx]
- add [_rand_table+edx],1239876
- pop edx
-
- r_a: add eax,[_rand_table+edx]
-
- pop edx
- mov [_rnd1],eax
- ret
-
- rand32_ endp
-
- ; eax - desired two pow interval
- ; edx - desired interval
-
- public randpowint_
-
- randpowint_ proc near
-
- push ebx
- mov ebx,eax
-
- get_another:
- ; unrolling starts
- push edx
- mov edx,[_rnd3]
- mov eax,[_rnd1]
- and edx,03FFh
-
- mul edx
- inc [_rnd2]
- mov edx,[_rnd2]
- and edx,16383
- jne pir_a
-
- push edx
- shr edx,14
- add [_rnd3],3
- and edx,16383
- add eax,[_rand_table+edx]
- add [_rand_table+edx],1239876
- pop edx
-
- pir_a: add eax,[_rand_table+edx]
- pop edx
- mov [_rnd1],eax
- ; unrolling stops
-
- and eax,ebx
- cmp eax,edx
- jae get_another
-
- pop ebx
-
- ret
-
-
- randpowint_ endp
-
-
- public randinter_
-
- randinter_ proc near
- push edx
- push ecx
- push eax
-
- frl00: xor ecx,ecx
- cmp eax,010000h
- jb frl0
- shr eax,16
- add cl,16
-
- frl0: cmp eax,0100h
- jb frl1
- shr eax,8
- add cl,8
-
- frl1: cmp eax,010h
- jb frl2
- shr eax,4
- add cl,4
-
- frl2: cmp eax,04h
- jb frl3
- shr eax,2
- add cl,2
-
- frl3: cmp eax,2
- jb frl4
- inc ecx
-
- frl4: inc cl
- mov edx,1
- shl edx,cl
- pop ecx
- dec edx ; eax now holding 2pow interval
-
- gget_another:
-
- ; unrolling starts
- push edx
- mov edx,[_rnd3]
- mov eax,[_rnd1]
- and edx,03FFh
-
- mul edx
- inc [_rnd2]
- mov edx,[_rnd2]
- and edx,16383
- jne ir_a
-
- push edx
- shr edx,14
- add [_rnd3],3
- and edx,16383
- add eax,[_rand_table+edx]
- add [_rand_table+edx],1239876
- pop edx
-
- ir_a: add eax,[_rand_table+edx]
- pop edx
- mov [_rnd1],eax
- ; unrolling stops
-
- and eax,edx
- cmp eax,ecx
- jae gget_another
-
- pop ecx
- pop edx
- ret
-
- randinter_ endp
-
-
-
- public ffsmul_
-
- ; eax - contains fixfloat 1
- ; edx - contains fixfloat 2
- ; routine affects edx due to 64 bit multiplication
-
- ffsmul_ proc near
- imul edx
- shrd eax,edx,16
- ret
- ffsmul_ endp
-
-
- public ffsdiv_
-
- ; eax contains denominator (Above division line)
- ; edx contains nominator (Below division line)
-
- ffsdiv_ proc near
-
- push edx
- push ecx
- push ebx
-
- or eax,eax
- mov ecx,edx
- mov bl,0
- jns fsd_1
-
- neg eax
- inc bl
-
- fsd_1: or ecx,ecx
- mov edx,eax
- jns fsd_2
-
- neg ecx
- inc bl
-
- fsd_2: shr edx,16
- shl eax,16
- cmp edx,ecx
- jae div_by_0
-
- div ecx
- test bl,1
- pop ebx
- pop ecx
- pop edx
- je fsd_3
-
- neg eax
- fsd_3: ret
-
- div_by_0: test bl,1
- pop ebx
- pop ecx
- pop edx
- jne dbz1
- mov eax,07FFFFFFFh
- ret
-
- dbz1: mov eax,080000000h
- ret
-
- ffsdiv_ endp
-
-
- public ffmul_
-
- ; eax - contains fixfloat 1
- ; edx - contains fixfloat 2
- ; routine affects edx due to 64 bit multiplication
-
- ffmul_ proc near
-
- mul edx
- shrd eax,edx,16
- ret
-
- ffmul_ endp
-
-
- public ffdiv_
-
- ; eax contains denominator (Above division line)
- ; edx contains nominator (Below division line)
-
- ffdiv_ proc near
-
- push edx
- push ecx
- mov ecx,edx
- mov edx,eax
- shl eax,16
- shr edx,16
- cmp edx,ecx
- jae div_by_00
-
- div ecx
- pop ecx
- pop edx
- ret
-
- div_by_00:
- pop ecx
- pop edx
- mov eax,0FFFFFFFFh
- ret
-
- ffdiv_ endp
-
-
-
- public ffsin_
- public ffcos_
- ffcos_:
- add eax,04000h ; that's all there is to it !
-
- ffsin_ proc near
-
- push ebx
- test eax,08000h
- setne bl
- and eax,07FFFh
- cmp eax,04000h
- jb fsn1
- xor eax,07FFFh
- fsn1: shr eax,2 ; increased resolution 4 times
- mov ax,[_sin_table+eax*2]
- or bl,bl
- je ffsn2
- neg eax
- ffsn2: pop ebx
- ret
-
- ffsin_ endp
-
- public ffasin_
- ffasin_ proc near
-
- push ebx
- or eax,eax
- mov bl,0
- jns fasn2
- neg eax
- inc ebx
-
- fasn2: and eax,0FFFFh
- shr eax,4
- mov ax,[_asin_table+eax*2]
- or bl,bl
- je fasn1
- neg eax
- fasn1: pop ebx
- ret
-
- ffasin_ endp
-
- public ffacos_
- ffacos_ proc near
-
- push ebx
- or eax,eax
- mov bl,0
- jns facn2
- neg eax
- inc ebx
-
- facn2: and eax,0FFFFh
- shr eax,4
- mov ax,[_asin_table+eax*2]
- or bl,bl
- je facn1
- neg eax
- facn1: pop ebx
- sub eax,04000h
- neg eax
- ret
-
- ffacos_ endp
-
-
- public fftan_
- fftan_ proc near
-
- push ebx
-
- test eax,4000h
- mov bl,0
- je ftn1
- test eax,3FFFh
- jne ftn01
- mov eax,030000000h ; almost infinity
- pop ebx
- ret
-
- ftn01: neg eax
- inc bl
-
- ftn1: and eax,03FFFh
- cmp eax,03C00h
- jae ftn3
-
- shr eax,4 ; lowest tan interval
- or bl,bl
- mov eax,[_tan_table1+eax*4]
- je ftn11
- neg eax
- ftn11: pop ebx
- ret
-
-
- ftn3: cmp eax,03F00h
- jae ftn4
-
- and eax,03fch
- or bl,bl
- mov eax,[_tan_table3+eax]
- je ftn31
- neg eax
- ftn31: pop ebx
- ret
-
- ftn4: and eax,0FFh
- or bl,bl
- mov eax,[_tan_table4+eax*4]
- je ftn41
- neg eax
- ftn41: pop ebx
- ret
-
- fftan_ endp
-
-
- public ffatan_
-
- ffatan_ proc near
-
- push ebx
- or eax,eax
- mov bl,0
- jns fat0
- neg eax
- inc ebx
-
- fat0: cmp eax,040000h
- jae fat1
- shr eax,8
- or bl,bl
- mov ax,[_atan_table1+eax*2]
- je fat01
- neg eax
- fat01: pop ebx
- ret
-
- fat1: cmp eax,0100000h
- jae fat2
- shr eax,12
- or bl,bl
- mov ax,[_atan_table2+eax*2]
- je fat11
- neg eax
- fat11: pop ebx
- ret
-
- fat2: cmp eax,02000000h ; 512.0
- jae fat3
- shr eax,17
- or bl,bl
- mov ax,[_atan_table3+eax*2]
- je fat21
- neg eax
- fat21: pop ebx
- ret
-
- fat3: cmp eax,020000000h ; 8192.0
- jae fat4
- shr eax,21
- or bl,bl
- mov ax,[_atan_table4+eax*2]
- je fat31
- neg eax
- fat31: pop ebx
- ret
-
- fat4: or bl,bl
- mov eax,03FFFh ; almost 90 degrees
- jns fat31
- neg eax
- jmp fat31
-
- ffatan_ endp
-
-
- public fflog2_
-
- fflog2_ proc near
-
- push ecx
- push ebx
-
- or eax,eax
- mov ebx,eax
- jne ffl00
- mov eax,80000000h ; approx -infinity
- pop ebx
- pop ecx
- ret
-
- ffl00: xor ecx,ecx
- cmp eax,010000h
- jb ffl0
- shr eax,16
- add cl,16
-
- ffl0: cmp eax,0100h
- jb ffl1
- shr eax,8
- add cl,8
-
- ffl1: cmp eax,010h
- jb ffl2
- shr eax,4
- add cl,4
-
- ffl2: cmp eax,04h
- jb ffl3
- shr eax,2
- add cl,2
-
- ffl3: cmp eax,2
- jb ffl4
- inc ecx
-
- ffl4: mov eax,ebx
- mov bl,cl
- sub cl,12
- js ffl5
- shr eax,cl
- jmp ffl6
-
- ffl5: neg cl
- shl eax,cl
-
- ffl6: sub eax,01000h
- sub bl,16
- mov cx,[_log2_table+eax*2]
- movsx eax,bl
- pop ebx
- shl eax,16
- mov ax,cx
-
- pop ecx
- ret
-
- fflog2_ endp
-
- public ffexp2_
-
- ffexp2_ proc near
- ; test eax,0FFFFh
- push ecx
- mov ecx,eax
- ; je fenodec
-
- shr eax,4
- sar ecx,16
- js fe1
- and eax,0FFFh
- mov ax,[_exp2_table+eax*2]
- add eax,10000h
- shl eax,cl
- pop ecx
- ret
-
- fe1: and eax,0FFFh
- neg cl
- mov ax,[_exp2_table+eax*2]
- add eax,10000h
- shr eax,cl
- pop ecx
- ret
-
- fenodec: sar ecx,16
- mov eax,1
- add ecx,16
- shl eax,cl
- pop ecx
- ret
-
- ffexp2_ endp
-
- public ffpow_
-
- ffpow_ proc near ; neat procedure eh?
-
- call fflog2_
- call ffsmul_
- call ffexp2_
- ret
-
- ffpow_ endp
-
- public ffsqrt_
-
- ffsqrt_ proc near
-
- push ecx
- push ebx
-
- or eax,eax
- mov ebx,eax
- jne ffs00
- mov eax,0h ; sqrt 0 = 0
- pop ebx
- pop ecx
- ret
-
- ffs00: xor ecx,ecx
- cmp eax,010000h
- jb ffs0
- shr eax,16
- add cl,16
-
- ffs0: cmp eax,0100h
- jb ffs1
- shr eax,8
- add cl,8
-
- ffs1: cmp eax,010h
- jb ffs2
- shr eax,4
- add cl,4
-
- ffs2: cmp eax,04h
- jb ffs3
- shr eax,2
- add cl,2
-
- ffs3: cmp eax,2
- jb ffs4
- inc ecx
-
- ffs4: mov eax,ebx
- sub cl,15
- test cl,1
- je ffs5
- inc cl
-
- ffs5: mov bl,cl
- add cl,4
- jns ffs6
- neg cl
- shl eax,cl
- jmp ffs7
-
- ffs6: shr eax,cl
-
- ffs7: sar bl,1
- mov ax,[_sqrt_table+eax*2]
- or bl,bl
- mov cl,bl
- js ffs8
- shl eax,cl
-
- pop ebx
- pop ecx
- ret
-
- ffs8: neg cl
- pop ebx
- shr eax,cl
- pop ecx
- ret
-
- ffsqrt_ endp
-
-
- public fftrihyp_
-
- fftrihyp_ proc near
-
- push ecx
- push ebx
- fthp0: mov ebx,edx ; 2
- imul eax ; edx:eax - a
- mov ecx,edx
- fthp1: xchg eax,ebx ; ecx:ebx - a
- imul eax
- add ebx,eax ; 2 2
- pop eax
- adc ecx,edx ; edx:eax - a +b
- push eax
- fthp11: imul eax
- add eax,ebx
- adc edx,ecx
-
- je t_hi_reg_zero
-
- ; bsr ecx,edx
-
- ; code from here
- push edx
- xor ecx,ecx
- cmp edx,010000h
- jb bsr00
- shr edx,16
- add cl,16
-
- bsr00: cmp edx,0100h
- jb bsr01
- shr edx,8
- add cl,8
-
- bsr01: cmp edx,010h
- jb bsr02
- shr edx,4
- add cl,4
-
- bsr02: cmp edx,04h
- jb bsr03
- shr edx,2
- add cl,2
-
- bsr03: cmp edx,2
- jb bsr04
- inc ecx
-
- bsr04: pop edx
- ; to here replaces bsr with a factor 2.5 speed gain
-
- add cl,17
- test cl,1
- je fthp2
- inc ecx
- fthp2: mov ebx,ecx
- cmp cl,020h
- jae fthp20
- shrd eax,edx,cl
- jmp t_ready_to_root
-
- fthp20: sub cl,020h
- mov eax,edx ; 20 shifts
- shr eax,cl
- jmp t_ready_to_root
-
-
- t_hi_reg_zero:
- ; bsr ecx,eax
- ; code from here
- push eax
- xor ecx,ecx
- cmp eax,010000h
- jb bsr10
- shr eax,16
- add cl,16
-
- bsr10: cmp eax,0100h
- jb bsr11
- shr eax,8
- add cl,8
-
- bsr11: cmp eax,010h
- jb bsr12
- shr eax,4
- add cl,4
-
- bsr12: cmp eax,04h
- jb bsr13
- shr eax,2
- add cl,2
-
- bsr13: cmp eax,2
- jb bsr14
- inc ecx
-
- bsr14: pop eax
- ; to here replaces bsr with a factor 2.5 speed gain
-
- sub cl,15
- test cl,1
- je thrz1
- inc ecx
- thrz1: mov ebx,ecx
- or ecx,ecx
- js thrz2
- shr eax,cl
- jmp t_ready_to_root
-
- thrz2: neg ecx
- shl eax,cl
-
- t_ready_to_root:
- shr eax,4 ;
- mov ecx,ebx
- and eax,0fffh
- sub cl,16
- mov ax,[_sqrt_table+eax*2]
- sar cl,1
- js trtr1
- shl eax,cl
- pop ebx
- pop ecx
- ret
-
- trtr1: neg cl
- shr eax,cl
- pop ebx
- pop ecx
- ret
-
- fftrihyp_ endp
-
-
- public ffhyp_
-
- ffhyp_ proc near
-
- push ecx
- push ebx
-
- fhp0: mov ebx,edx ; 2
- imul eax ; edx:eax - a
- mov ecx,edx
- ; 2
- fhp1: xchg eax,ebx ; ecx:ebx - a
- imul eax
- add eax,ebx ; 2 2
- adc edx,ecx ; edx:eax - a + b
-
- je hi_reg_zero
-
- ; bsr ecx,edx
- ; code from here
- push edx
- xor ecx,ecx
- cmp edx,010000h
- jb bsr20
- shr edx,16
- add cl,16
-
- bsr20: cmp edx,0100h
- jb bsr21
- shr edx,8
- add cl,8
-
- bsr21: cmp edx,010h
- jb bsr22
- shr edx,4
- add cl,4
-
- bsr22: cmp edx,04h
- jb bsr23
- shr edx,2
- add cl,2
-
- bsr23: cmp edx,2
- jb bsr24
- inc ecx
-
- bsr24: pop edx
- ; to here replaces bsr with a factor 2.5 speed gain
-
-
- add cl,17
- test cl,1
- je fhp2
- inc ecx
- fhp2: mov ebx,ecx
- cmp cl,020h
- jae fhp20
- shrd eax,edx,cl
- jmp ready_to_root
-
- fhp20: sub cl,020h
- mov eax,edx ; 020h shifts
- shr eax,cl
- jmp ready_to_root
-
-
- hi_reg_zero:
- ; bsr ecx,eax
- ; code from here
- push eax
- xor ecx,ecx
- cmp eax,010000h
- jb bsr30
- shr eax,16
- add cl,16
-
- bsr30: cmp eax,0100h
- jb bsr31
- shr eax,8
- add cl,8
-
- bsr31: cmp eax,010h
- jb bsr32
- shr eax,4
- add cl,4
-
- bsr32: cmp eax,04h
- jb bsr33
- shr eax,2
- add cl,2
-
- bsr33: cmp eax,2
- jb bsr34
- inc ecx
-
- bsr34: pop eax
- ; to here replaces bsr with a factor 2.5 speed gain
-
-
- sub cl,15
- test cl,1
- je hrz1
- inc ecx
- hrz1: mov ebx,ecx
- or ecx,ecx
- js hrz2
- shr eax,cl
- jmp ready_to_root
-
- hrz2: neg ecx
- shl eax,cl
-
- ready_to_root:
- shr eax,4 ;
- mov ecx,ebx
- and eax,0fffh
- sub cl,16
- mov ax,[_sqrt_table+eax*2]
- sar cl,1
- js rtr1
- shl eax,cl
- pop ebx
- pop ecx
- ret
-
- rtr1: neg cl
- shr eax,cl
- pop ebx
- pop ecx
- ret
-
- ffhyp_ endp
-
-
-
- public ffalmosthyp_
-
- ffalmosthyp_ proc near
-
- or eax,eax
- push edx
- jns fah_1
- neg eax
-
- fah_1: or edx,edx
- jns fah_2
- neg edx
-
- fah_2: cmp eax,edx
- jae fah_3
- xchg eax,edx
-
- fah_3: shr edx,1
- add eax,edx
- pop edx
- ret
-
- ffalmosthyp_ endp
-
-
-
- public ffmuldiv_
-
-
- ffmuldiv_ proc near
-
- push esi
- push ebx
- push ecx
-
- push eax
- push edx
-
-
- ffmd5: mov eax,ebx
- imul ecx
- je ffmd_zero_nominator
- mov ebx,eax
- mov ecx,edx
- mov eax,[esp]
- mov edx,[esp+4]
- imul edx
-
- or edx,edx
- mov esi,edx ; sign of nominator
- jns ffmd51
- neg eax ; negating denominator
- neg edx
-
- ffmd51: or ecx,ecx
- jns ffmd52
- xor esi,0x80000000 ; change sign of result
-
- not ebx
- not ecx
-
- ffmd52: cmp edx,0xFFFF
- ja ffmd520
- shld edx,eax,16
- shl eax,16
- or ecx,ecx
- jmp ffmd521
-
- ffmd520: shrd ebx,ecx,16
- shr ecx,16
-
- ffmd521: jne ffmd_more_shift
- cmp edx,ebx
- jae ffmd_overflow
-
- idiv ebx ; there is no test for overflow
- or esi,esi
- pop edx ; in this division
- jns ffmd53
- neg eax
-
- ffmd53: add esp,4
- pop ecx
- pop ebx
- pop esi
- ret
-
-
- ffmd_more_shift:
- shrd eax,edx,16
- shr edx,16
- shrd ebx,ecx,16
- cmp edx,ebx
- jae ffmd_overflow
- idiv ebx
- or esi,esi
- pop edx
- jns ffmd54
- neg eax
-
- ffmd54: add esp,4
- pop ecx
- pop ebx
- pop esi
- ret
-
- ffmd_overflow:
- pop edx
- add esp,4
- or esi,esi
- js ffmd6
- mov eax,07FFFFFFFh
- pop ecx
- pop ebx
- pop esi
- ret
-
- ffmd_zero_nominator:
- pop edx
- pop eax
- xor eax,edx
- js ffmd6
-
- mov eax,07FFFFFFFh ; positive infinity
- pop ecx
- pop ebx
- pop esi
- ret
-
- ffmd6: mov eax,080000000h ; negative infinity
- pop ecx
- pop ebx
- pop esi
- ret
-
- ffmuldiv_ endp
-
-
- public ffmmd_
- ffmmd_ proc near
-
- push esi
- push ebx
- xor esi,esi
- push edx
-
- ffmmd2: imul edx
- jns ffmmd3
-
- neg edx
- neg eax
-
- inc esi
-
- ffmmd3: or ebx,ebx
- jns ffmmd4
-
- neg ebx
- dec esi
-
- ffmmd4: cmp edx,ebx
- jae ffmmd_overflow
- div ebx
- or esi,esi
- pop edx
- je ffmmd5
- neg eax
-
- ffmmd5: pop ebx
- pop esi
- ret
-
- ffmmd_overflow:
- or esi,esi
- pop edx
- pop ebx
- pop esi
- js ffmmd6
-
- mov eax,07FFFFFFFh
- ret
-
- ffmmd6: mov eax,080000000h
- ret
-
-
- ffmmd_ endp
-
-
-
- public ffortproj_
-
- ; eax - a
- ; edx - b
- ; ebx - c
- ; ecx - d
-
- ; returns (a*b+c*d)/(a*a+c*c)
-
- ffortproj_ proc near
-
- push ebx
- push edx
- push ecx
-
- sar eax,5
- sar edx,5
- sar ebx,5
- sar ecx,5
- push eax
-
- call ffsmul_ ; eax = a*b
- push eax
-
- mov eax,ebx
- mov edx,ecx
- call ffsmul_ ; eax = c*d
-
- pop ecx ; ecx = a*b
- add ecx,eax ; ecx = a*b + c*d
-
- mov eax,ebx
- mov edx,ebx
- call ffsmul_
- mov ebx,eax ; ebx = c*c
-
- pop eax
- mov edx,eax
- call ffsmul_ ; eax = a*a
-
- add ebx,eax ; ebx = c*c + a*a
- mov eax,ecx
- mov edx,ebx
- call ffsdiv_
-
- pop ecx
- pop edx
- pop ebx
-
- ret
-
- ffortproj_ endp
-
-
- public ffortproj1_
-
- ; eax - a
- ; edx - b
- ; ebx - c
- ; ecx - d
-
- ; returns (a*b+c*d)/sqrt(a*a+c*c)
-
- ffortproj1_ proc near
-
- push ebx
- push edx
- push ecx
-
- sar eax,6
- sar edx,6
- sar ebx,6
- sar ecx,6
- push eax
-
- call ffsmul_ ; eax = a*b
- push eax
-
- mov eax,ebx
- mov edx,ecx
- call ffsmul_ ; eax = c*d
-
- pop ecx ; ecx = a*b
- add ecx,eax ; ecx = a*b + c*d
-
- mov eax,ebx
- mov edx,ebx
- call ffsmul_
- mov ebx,eax ; ebx = c*c
-
- pop eax
- mov edx,eax
- call ffsmul_ ; eax = a*a
-
- add eax,ebx ; ebx = c*c + a*a
- call ffsqrt_ ; root it
-
- mov edx,eax
- mov eax,ecx
-
- call ffsdiv_
- shl eax,6 ; compensating root
-
- pop ecx
- pop edx
- pop ebx
-
- ret
-
- ffortproj1_ endp
-
- public ffdot_through_hyps_
-
- ; eax - a
- ; edx - b
- ; ebx - c
- ; ecx - d
-
- ; returns (a*b+c*d)/(sqrt(a*a+c*c)*sqrt(b*b+d*d))
-
- ffdot_through_hyps_ proc near
-
- push ebx
- push edx
- push ecx
-
- sar eax,5
- sar edx,5
- sar ebx,5
- sar ecx,5
-
- push edx
- push ecx
- push eax
-
- call ffsmul_ ; eax = a*b
- push eax
-
- mov eax,ebx
- mov edx,ecx
- call ffsmul_ ; eax = c*d
-
- pop ecx ; ecx = a*b
- add ecx,eax ; ecx = a*b + c*d
-
- mov eax,ebx
- mov edx,ebx
- call ffsmul_
- mov ebx,eax ; ebx = c*c
-
- pop eax
- mov edx,eax
- call ffsmul_ ; eax = a*a
-
- add eax,ebx
- call ffsqrt_
- mov ebx,eax ; ebx = sqrt(c*c + a*a)
-
- pop eax
- mov edx,eax
- call ffsmul_ ; eax = d*d
-
- pop edx
- push eax
- mov eax,edx
- call ffsmul_ ; eax = b*b
-
- pop edx
- add eax,edx
- call ffsqrt_ ; eax = sqrt(d*d + b*b)
-
- mov edx,ebx
- call ffmul_ ; eax = sqrt(d*d + b*b) * sqrt(c*c + a*a)
-
- mov edx,eax
- mov eax,ecx
- call ffsdiv_ ; eax = a*b + c*d / (sqrt(d*d + b*b) * sqrt(c*c + a*a))
-
- pop ecx
- pop edx
- pop ebx
-
- ret
-
- ffdot_through_hyps_ endp
-
-
- public isqrt_
-
- isqrt_ proc near
-
- push ecx
- push edx
- push eax
-
- ; bsr ecx,eax ; unfold
-
- ; code from here
-
- xor ecx,ecx
- cmp eax,010000h
- jb is30
- shr eax,16
- add cl,16
-
- is30: cmp eax,0100h
- jb is31
- shr eax,8
- add cl,8
-
- is31: cmp eax,010h
- jb is32
- shr eax,4
- add cl,4
-
- is32: cmp eax,04h
- jb is33
- shr eax,2
- add cl,2
-
- is33: cmp eax,2
- jb is34
- inc ecx
-
- is34:
- ; to here replaces bsr with a factor 2.5 speed gain
-
- mov edx,ecx
- sub cl,10
- neg edx
- test cl,1
- pop eax
- je is1
-
- inc edx
- dec ecx
- is1:
- add dl,31
- or cl,cl
- js is2
- shr eax,cl
- jmp is3
-
- is2:
- neg cl
- shl eax,cl
-
- is3:
- shr dl,1
- mov ax,[_sqrt_table+eax*2]
- mov ecx,edx
- pop edx
- shr eax,cl
- pop ecx
- ret
-
- isqrt_ endp
-
-
-
- ; eax - denominator lo part
- ; edx - denominator hi
- ; ebx - nominator
- ; ecx - pointer to DWORD location to store
- ; decimal fraction of result.
-
- ; returns the integer part of result
- ; works with signed 64 bit quantities
- ; this routine does not check for any zero divisions
-
-
- public ff_double_div_
-
- ff_double_div_ proc near
-
- push edx
- push edi
-
- xor edi,edi
- or edx,edx
- jns dd_1
-
- neg edx
- neg eax ; make both numbers positive
- sbb edx,0
- inc edi
-
- dd_1: or ebx,ebx
- jns dd_2
- neg ebx
- inc edi
-
- dd_2: div ebx
- push eax ; this is integer part of
- ; division
-
- xor eax,eax ; produce decimal part of
- div ebx ; division
-
- pop edx ; eax - decpart, edx - intpart
-
- dd_4: test edi,1
- je dd_5
-
- neg edx ; negate integer part
- neg eax ; negate decimal part
- sbb edx,0 ; dec if non zero eax
-
- dd_5: mov [ecx],eax ; store away decimal fraction
- mov eax,edx ; return integer fraction
-
- dd_restore_reg:
- pop edi ; restore registers
- pop edx
-
- ret
-
- ff_double_div_ endp
-
- ;
- ; eax - pointer to low value
- ; edx - pointer to hi value
- ; ebx - 0 - ordinary shift
- ; no 0 - arithmetic shift
- ; ecx - nr of steps to shift,
- ; right is positive,
- ; left is negative
- ;
-
- public ff_double_shift_
-
- ff_double_shift_ proc near
-
- push esi
- or ecx,ecx
- js dr_left
-
- ; rotate right
- mov esi,[edx]
- shrd [eax],esi,cl
- xor esi,esi
- or ebx,ebx
- jne dr_aritm
-
- shrd [edx],esi,cl
- pop esi
- ret
-
- dr_aritm: mov esi,[edx]
- sar esi,31
- shrd [edx],esi,cl
- pop esi
- ret
-
- ; shift left
- dr_left: push ecx
- neg ecx
- mov esi,[eax]
- shld [edx],esi,cl
- xor esi,esi
- shld [eax],esi,cl
- pop ecx
- pop esi
- ret
-
- ff_double_shift_ endp
- ; /\ Y
- ; |
- ; This routine takes a | o (1,2)
- ; vector in it's rectangular form | /
- ; and returns the angle it forms | /\ V = atan(2/1)
- ; in relation to the point (1,0). |/ |
- ; that is coordinate (0,1) will return -------------> X
- ; (90/360)*65536 ,
- ; coordinate (0,-1) will return
- ; ((-90/360)*65536) & 65535
- ;
- ; renember, there are 65536 degrees in
- ; a circle in fixfloat universe.
-
-
- ; eax - x component
- ; edx - y component
-
- ; returns result in eax
-
- public ff_vec_to_ang_
-
- ff_vec_to_ang_ proc near
-
- or eax,eax
- push edx
- push ecx
- mov cl,0
- js ff_fta0
-
- jne ff_fta1
- or edx,edx
- je ff_zero_vector
- jmp ff_fta1
-
- ff_fta0:
- neg eax ; make sure x component is positive
- neg edx
- inc cl ; flag that we have to subtract/add '180' degrees to angle
-
- ff_fta1:
- cmp edx,eax ; test if y>x
- jge ff_y_bigger
- push edx
- neg edx
- cmp edx,eax ; test if -y>x
- pop edx
- jge ff_y_bigger
- ; abs(x)>abs(y)
- xchg eax,edx ; put y on top in divisor, x in bottom
- call ffsdiv_ ; divide
- call ffatan_ ; arc tan
- jmp ff_fta2
-
- ff_y_bigger: ; abs(y)>abs(x)
- push 0004000h
- or edx,edx
- jns ff_yb1
- mov DWORD PTR[esp],000c000h
-
- ff_yb1: call ffsdiv_
- call ffatan_
- neg eax
- pop edx
- add eax,edx
-
- ff_fta2:
- or cl,cl ; see if need to flip angle '180' degrees
- pop ecx
- je ff_fta3
-
- xor eax,08000h ; flip it
-
- ff_fta3:
- and eax,0FFFFh
- pop edx
- ret
-
- ff_zero_vector:
- xor eax,eax
- pop ecx
- pop edx
- ret
-
- ff_vec_to_ang_ endp
-
- ;
-
- ; this routine solves a 2:nd degree equation
- ; by std formula, for given p & 1 :
- ;
- ; 2
- ; x + px + q = 0
- ;
- ; setup at call :
- ; eax - p
- ; edx - q
- ; ebx - pointer to where to put conjugate part ( the +/- term )
- ; ecx - pointer to where to put prefix part (-p/2)
- ;
- ; returns eax - 0 if solved OK
- ; returns eax - no 0 if no real roots
- ;
- ; routine handles cases where p*p/4-q>32767 correctly,
- ; since it uses intermediate 64 bit representation
- ;
-
- public ff_solve_2nd_poly_
-
- ff_solve_2nd_poly_ proc near
-
- push edx
- push ecx
- push eax
-
- mov ecx,edx ; square the p term
- mov edx,eax
- imul edx
- shrd eax,edx,18 ; work with 64 bits for a while
- sar edx,18
- or ecx,ecx ; slightly different behaviour if negative q value
- js ff2nd_1
-
- sub eax,ecx
- sbb edx,0
- jmp ff2nd_2
-
- ff2nd_1:
- neg ecx
- add eax,ecx
- adc edx,0
-
- ff2nd_2:
- js ff2nd_no_real_roots ; such things happens...
- xor ecx,ecx
- or edx,edx
- je ff2nd_4
-
- ff2nd_3:
- shrd eax,edx,2 ; enable momentary overflow but still give correct result
- inc ecx ; with the help of afew shifts
- shr edx,2
- jne ff2nd_3
-
- ff2nd_4:
- call ffsqrt_
- shl eax,cl
- mov [ebx],eax ; storing conjugate
-
- pop eax
- pop ecx
- neg eax ; calc -p/2
- pop edx
- sar eax,1
- mov [ecx],eax
- xor eax,eax ; indicate we did OK
- ret
-
- ff2nd_no_real_roots:
- pop eax
- pop ecx
- neg eax
- pop edx
- sar eax,1
- mov [ecx],eax
- mov al,1 ; indicate no real roots
- ret
-
- ff_solve_2nd_poly_ endp
-
- _TEXT ENDS
- END
-
-
-
-
-
-
-
-